package community.hospital.controller;

import com.google.common.collect.Lists;

import community.hospital.annotation.Log;
import community.hospital.annotation.Module;
import community.hospital.annotation.NeedLogin;
import community.hospital.annotation.NeedPermission;
import community.hospital.common.Add;
import community.hospital.common.BaseRemove;
import community.hospital.common.R;
import community.hospital.common.Update;
import community.hospital.entity.Department;
import community.hospital.entity.request.DepartmentRequest;
import community.hospital.entity.request.ListDepartmentRequest;
import community.hospital.entity.response.*;
import community.hospital.service.application.DepartmentApplicationService;
import community.hospital.service.application.HospitalApplicationService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static community.hospital.common.Constant.*;
import static community.hospital.common.PermissionConstant.*;

/**
 * @author yindingjie
 */
@RestController
@RequestMapping("/department")
@Module("科室")
public class DepartmentController {
    @Resource
    private DepartmentApplicationService departmentApplicationService;
    @Resource
    private HospitalApplicationService hospitalApplicationService;

    @PostMapping("/listDepartment")
    @NeedLogin
//    @NeedPermission(role = SUPER_ADMIN, permission = LIST_DEPARTMENT)
    @Log(methodName = LOG_QUERY, desc = "查询科室")
    public R<List<DepartmentResponse>> listDepartment(@RequestBody ListDepartmentRequest request) {
        List<DepartmentResponse> responseList = departmentApplicationService.listDepartment(request);
        return R.ok(responseList);
    }

    @Log(methodName = LOG_INSERT, desc = "新增科室")
    @PostMapping("/addDepartment")
    @NeedLogin
    @NeedPermission(role = SUPER_ADMIN, permission = ADD_DEPARTMENT)
    public R<Boolean> addDepartment(@Validated(Add.class) @RequestBody DepartmentRequest request) {
        Boolean isOk = departmentApplicationService.addDepartment(request);
        return R.ok(isOk);
    }

    @Log(methodName = LOG_UPDATE, desc = "更新科室")
    @PostMapping("/updateDepartment")
    @NeedLogin
    @NeedPermission(role = SUPER_ADMIN, permission = UPDATE_DEPARTMENT)
    public R<Boolean> updateDepartment(@Validated(Update.class) @RequestBody DepartmentRequest request) {
        Boolean isOk = departmentApplicationService.updateDepartment(request);
        return R.ok(isOk);
    }

    @Log(methodName = LOG_REMOVE, desc = "删除科室")
    @PostMapping("/removeDepartment")
    @NeedLogin
    @NeedPermission(role = SUPER_ADMIN, permission = REMOVE_DEPARTMENT)
    public R<Boolean> removeDepartment(@Valid @RequestBody BaseRemove baseRemove) {
        Boolean isOk = departmentApplicationService.removeDepartment(baseRemove.getIds());
        return R.ok(isOk);
    }

    @GetMapping("/getDepartmentOption")
    public R<List<DepartmentOptionResponse>> getDepartmentOption(Long hospitalId) {
        List<DepartmentOptionResponse> departmentResponseList = departmentApplicationService.getDepartmentOption(hospitalId);
        return R.ok(departmentResponseList);
    }

    @NeedLogin
    @NeedPermission(role = SUPER_ADMIN, permission = UPDATE_DEPARTMENT)
    @PostMapping("/updateState")
    public R<Boolean> updateStatus(@RequestBody DepartmentRequest departmentRequest) {
        Boolean isOk = departmentApplicationService.updateStatus(departmentRequest);
        return R.ok(isOk);
    }

    @GetMapping("/listAllHospitalAndDepartment")
    public R<List<OptionResp>> listAllHospitalAnd1Department() {
        List<HospitalResponse> hospitalResponses = hospitalApplicationService.listOptionHospital();
        List<DepartmentResponse> departmentResponses =  departmentApplicationService.listAllDepartment();
        //一级科室
        List<OptionResp> departResps = departmentResponses
                .stream()
                .filter(departmentResponse -> departmentResponse.getPid().equals(0L))
                .map(departmentResponse -> {
                    OptionResp optionResp = new OptionResp();
                    optionResp.setValue(departmentResponse.getId());
                    optionResp.setPid(departmentResponse.getHospitalId());
                    optionResp.setKey(departmentResponse.getId());
                    optionResp.setLabel(departmentResponse.getDeptName());
                    optionResp.setTitle(departmentResponse.getDeptName());
                    return optionResp;
                }).collect(Collectors.toList());
        //递归找子科室
        getChildren(departResps, departmentResponses);
        List<OptionResp> response = hospitalResponses.stream().map(resp -> {
            OptionResp optionResp = new OptionResp();
            optionResp.setValue(resp.getId());
            optionResp.setKey(resp.getId());
            optionResp.setLabel(resp.getName());
            optionResp.setTitle(resp.getName());
            //找出医院对应的科室
            List<OptionResp> departments = departResps.stream().filter(departResp -> departResp.getPid().equals(resp.getId())).collect(Collectors.toList());
            optionResp.setChildren(departments);
            return optionResp;
        }).collect(Collectors.toList());
        return R.ok(response);
    }

    private void getChildren(List<OptionResp> optionResps,List<DepartmentResponse> departmentResponses) {
        optionResps.forEach(depart1Resp -> {
            List<OptionResp> childrenList = departmentResponses
                    .stream()
                    .filter(departmentResponse -> departmentResponse.getPid().equals(depart1Resp.getKey()))
                    .map(children -> {
                        OptionResp optionResp = new OptionResp();
                        optionResp.setValue(children.getId());
                        optionResp.setKey(children.getId());
                        optionResp.setLabel(children.getDeptName());
                        optionResp.setTitle(children.getDeptName());
                        return optionResp;
                    }).collect(Collectors.toList());
            depart1Resp.setChildren(childrenList);
            getChildren(childrenList,departmentResponses);
        });
    }

    @GetMapping("/listDeptByHospitalId")
    public R<List<OptionResp>> listDeptByHospitalId(Long hospitalId){
        List<OptionResp> optionRespList = departmentApplicationService.listByHospitalId(hospitalId);
        return R.ok(optionRespList);
    }
}
